package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.ServiceException;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.Software;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.SoftwareService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 软件
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/9/7 1:09
 */
@RequestMapping("/software")
@RestController
@Slf4j
public class SoftwareController {

    @Autowired
    private SoftwareService softwareService;
    @Autowired
    private DictService dictService;


    /**
     * 获取当前电脑安装的软件
     * @return
     */
    @PostMapping("/getCurrComputerSoftware")
    public ResultJson getCurrComputerSoftware(){
        List<Software> softwareList = getInstalledSoftwareViaPowerShell();
        return ResultJson.success(softwareList);
    }

    /**
     * 分页查询软件信息
     * @param page 分页参数
     * @param software 查询参数
     * @return
     */
    @PostMapping("/getSoftwareListPage")
    public ResultJson getSoftwareListPage(Page page, Software software){
        if (software == null){
            software = new Software();
        }
        software.setUserId(StpUtil.getLoginIdAsString());

        return ResultJson.success(softwareService.getSoftwareListPage(page, software));
    }

    /**
     * 物理删除应用
     * @param id 应用ID
     * @return
     */
    @ApiIdempotent
    @PostMapping("/delSoftwareById")
    public ResultJson delSoftwareById(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        softwareService.removeById(id);
        return ResultJson.success(null);
    }

    /**
     * 更新软件信息
     * @param software 软件信息
     * @return
     */
    @PostMapping("/updSoftware")
    @ApiIdempotent
    public ResultJson updSoftware(@Validated(UpdGroup.class) Software software){
        String msg = checkSoftware(software);
        if (msg != null){
            return ResultJson.error(msg);
        }

        EntityTool.buildUpdBase(software, StpUtil.getLoginIdAsString());
        softwareService.updateById(software);
        return ResultJson.success(software);
    }

    /**
     * 保存软件信息
     * @param software 软件信息
     * @return
     */
    @PostMapping("/saveSoftware")
    @ApiIdempotent
    public ResultJson saveSoftware(@Validated(AddGroup.class) Software software){
        String msg = checkSoftware(software);
        if (msg != null){
            return ResultJson.error(msg);
        }

        software.setId(IdTool.getId());
        software.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(software, StpUtil.getLoginIdAsString());
        softwareService.save(software);
        return ResultJson.success(software);
    }


    /**
     * 获取软件类型
     * @return
     */
    @PostMapping("/getSoftwareType")
    public ResultJson<List<Dict>> getSoftwareType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.SOFTWARE_GROUP, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }

    /**
     * 软件信息校验
     * @param software 软件信息
     * @return 返回非null都是有问题的
     */
    private String checkSoftware(Software software){
        Software softwareDb = softwareService.getSoftwareRepeatQuery(software.getId(), StpUtil.getLoginIdAsString(), software.getName(), software.getApp());
        if (softwareDb != null){
            return "该应用已入库，不需要重复录入";
        }

        return null;
    }

    /**
     * 通过PowerShell命令获取安装的软件列表
     * @return
     */
    public List<Software> getInstalledSoftwareViaPowerShell() {
        List<Software> softwareList = new ArrayList<>();

        try {
            // 使用PowerShell命令获取软件列表
            String command = "powershell.exe \"Get-ItemProperty " +
                    "HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*," +
                    "HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*," +
                    "HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | " +
                    "Select-Object DisplayName, DisplayVersion, Publisher, InstallLocation | " +
                    "Where-Object { $_.DisplayName -ne $null } | " +
                    "Sort-Object DisplayName\"";

            Process process = Runtime.getRuntime().exec(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));

            String line;
            boolean isHeader = true;

            while ((line = reader.readLine()) != null) {
                line = line.trim();

                if (line.isEmpty() || isHeader) {
                    isHeader = false;
                    continue;
                }

                // 解析PowerShell输出
                Software software = parsePowerShellOutput(line);
                if (software != null && software.getName() != null) {
                    softwareList.add(software);
                }
            }

            process.waitFor();

        } catch (IOException | InterruptedException e) {
            log.error("软件读取出现异常", e);
            throw new ServiceException("软件读取出现异常");
        }

        return softwareList;
    }

    /**
     * 解析数据并组装
     * @param line 一行数据
     * @return
     */
    private Software parsePowerShellOutput(String line) {
        // 简单的解析逻辑，实际可能需要更复杂的解析.
        // 按多个空格分割
        String[] parts = line.split("\\s{2,}");

        if (parts.length >= 3) {
            Software software = new Software();
            software.setUserId(StpUtil.getLoginIdAsString());
            software.setApp(Constant.SoftwarePlatform.WIN);
            software.setName(parts[0].trim());
            software.setInUse(Constant.YesOrNo.YES);
            software.setTypeId("1568853974787956736");
            software.setLocalSaveAddress(null);
            software.setOfficialAddress(null);
            software.setGrade(3);
            if (parts.length > 3) {
                software.setDescribe(parts[2].trim() + "---" + parts[3].trim());
            } else {
                software.setDescribe(parts[2].trim());
            }
            software.setRemarks("PowerShell读取");

            return software;
        }

        return null;
    }
}
